💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    14 의존성이란 | ✅ 저자: 이유정(박사)

    의존성이란? (Dependency) 무언가에 의존한다는 뜻으로 함수나 클래스가 직접 만들지 않은 외부의 기능을 사용할 때, 그 외부 기능을 "의존성"이라고 해요.

    의존성은 왜 필요한가?

    1. 중복 제거 여러 함수에서 같은 파라미터나 로직이 필요할 때, 매번 똑같이 작성하면 비효율적이죠.
      → 이걸 한 군데로 모아서 Depends()로 가져오면 훨씬 깔끔해요.

    2. 코드 재사용성 특정 기능(예: 인증, 공통 쿼리 파라미터 등)을 여러 곳에서 재활용할 수 있어요.

    3. 유지보수 쉬움 의존성을 함수로 분리해두면 나중에 수정이 필요할 때 한 군데만 수정하면 돼요.

    4. 순서 제어 먼저 실행되어 선처리 가능

    5. 테스트 편의 가짜 의존성으로 교체 가능 (mocking)

    6. 문서 자동화 Swagger 문서에 자동 반영

    7. 보안 처리 인증, 권한 확인을 중앙 집중 관리

    8. 자원 관리 DB, 파일 등 자원 연결 → 해제 흐름을 의존성으로 구현 가능

    일반함수 호출과 비교하여 설명하겠습니다: 일반 함수 호출

    def read_items():
        user = get_current_user()
        return {"user": user}
    

    → 내가 직접 불러야 해요.
    get_current_user()를 안 쓰면 동작 안 해요.

    의존성 주입 사용

    from fastapi import Depends
    
    @app.get("/items/")
    def read_items(user = Depends(get_current_user)):
        return {"user": user}
    

    → FastAPI가 알아서:

    • get_current_user() 먼저 실행
    • user에 그 값을 넣어줌
    • 우리는 그냥 user만 쓰면 됨

    한마디로 요약하면 내가 함수호출을 해서 부르느냐, FastAPI가 대신 부르고 관리해주느냐, 의 차이입니다

    디렉토리 구조

    myproject/
    ├── main.py
    ├── dependencies/
    │   └── common.py
    

    dependencies/common.py

    from fastapi import Depends
    from typing import Annotated
    
    # 공통 쿼리 파라미터
    async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
        return {"q": q, "skip": skip, "limit": limit}
    
    # 의존성 타입으로 정의
    CommonsDep = Annotated[dict, Depends(common_parameters)]
    

    Annotated란? Annotated는 타입 힌트에 부가적인 의미를 덧붙일 때 사용하는 문법입니다. Annotated[기본타입, 부가정보] FastAPI에서는 이걸 통해 다음 두 가지 정보를 같이 전달합니다:

    • 데이터의 타입 (dict)
    • 어떻게 주입할 것인지 (Depends(...))

    Annotated[dict, 딕셔너리 형태로 사용한 이유는 리턴 형태가 딕셔너리 데이터 이기 때문입니다.


    main2.py

    from fastapi import FastAPI
    from dependencies.common import CommonsDep  # 의존성타입 변수
    
    app = FastAPI()
    
    @app.get("/items/")
    async def read_items(commons: CommonsDep):
        return commons
    
    @app.get("/users/")
    async def read_users(commons: CommonsDep):
        return commons
    

    사용자가 /items/?q=apple&skip=2 같은 요청을 보내면
    FastAPI가 자동으로 common_parameters()를 실행하고
    결과 딕셔너리인 {"q": "apple", "skip": 2, "limit": 100}commons 변수에 넣어줘요.

    실행예시:

    GET /items?q=hello&skip=1&limit=5
    

    응답:

    {
      "q": "hello",
      "skip": 1,
      "limit": 5
    }
    

    참고 예시코드: 특정 라우터에서만 사용(한 파일에 의존성 코드 표현)

    from fastapi import FastAPI, Depends
    
    app = FastAPI()
    
    # 의존성 함수 정의
    async def get_token_header(x_token: str = "default"):
        return x_token
    
    # 필요한 라우터에서만 사용
    @app.get("/items/")
    async def read_items(token: str = Depends(get_token_header)):
        return {"token": token}
    
    # 여긴 안 써도 됨!
    @app.get("/ping")
    async def ping():
        return {"message": "pong"}
    

    여러 개 주입도 가능

    async def get_user(): ...
    async def get_settings(): ...
    
    @app.get("/dashboard/")
    async def dashboard(
        user = Depends(get_user),
        settings = Depends(get_settings)
    ):
        return {"user": user, "settings": settings}
    
    TOP
    preload preload